"""
Mysql数据库连接及相关操作
注意事项：
1.连接数据库后务必要手动关闭
2.可执行多行sql语句，即有；分隔
3.非查询语句与查询语句分开执行，且查询语句只能单行执行
4.调用函数时使用select，调用exec_sql即可
"""
import pymysql
from pymysql.constants import CLIENT

from .Logger import Logger


class ComMysql:
    def __init__(self, host, port, user, password, database):
        self.host = host
        self.port = port
        self.user = user
        self.password = password
        self.database = database
        self.db = None
        self.log = Logger()

    def connect(self):
        """
        连接数据库
        """
        self.db = pymysql.connect(host=self.host,
                                  port=self.port,
                                  user=self.user,
                                  password=self.password,
                                  database=self.database,
                                  client_flag=CLIENT.MULTI_STATEMENTS,
                                  charset='utf8')

    def exec_sql(self, sql):
        """
        执行sql语句，可多行执行，即有；分隔
        查询语句与其他sql语句分开，且查询语句只能单行执行
        :param sql: sql语句
        :return: 查询结果
        """
        self.log.info(sql)
        with self.db.cursor() as cur:
            cur.execute(sql)
            values = cur.fetchall()
            self.db.commit()
        return values

    def exec_many_sql(self, sql, *args):
        """
        执行多行插入sql语句
        :param sql: 插入sql语句
        :param args: 多行插入值
        :return: 无
        """
        self.log.info(sql, args)
        with self.db.cursor() as cur:
            cur.executemany(sql, args)
            self.db.commit()

    def exec_proc(self, proc_name, *args):
        """
        调用存储过程
        :param proc_name: 存储过程名
        :param args: [入参1，入参2，出参1， 出参2……]
        :return: 返回值
        """
        with self.db.cursor(cursor=pymysql.cursors.DictCursor) as cur:
            cur.callproc(proc_name, args=args)
            res = cur.fetchall()
        return res

    def close(self):
        """
        关闭数据库连接
        """
        if self.db:
            self.db.close()
